<!--
 * @Description: 业务流程模型和标记法（Business Process Model and Notation）
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2024-07-09 13:42:36
 * @LastEditors: swc shanwenchao12138@163.com
 * @LastEditTime: 2025-09-06 18:52:26
-->

<template>
  <div class="init-container">
    <c-flowchart
      :compBoxInfo="GT_compBoxInfo"
      :config="conf"
      @compBoxInfo="cFlowchartMounted"
      @contextmenu-select="flowchartContextMenuSelected"
      @graphEditorState="graphEditorState"
    >
      <div slot="rightPanel" class="right-panel">
        <o-base-form
          :mode="1"
          @on-change="onRightFormAttrChange"
          @mounted="initRightForm"
        />
      </div>
    </c-flowchart>
    <o-modal
      v-model="openModal"
      :title="$srv.getI18nByValue('图库')"
      :size="[800, 800]"
      :mask="true"
      :tap-close="true"
      :keep-alive="true"
    >
      <div class="init-container" slot="content">
        <open-bpmn
          v-if="showOpenBpmn"
          @cell-dblclick="openBpmnDblclick"
          @bg-mounted="onBgMounted"
        ></open-bpmn>
        <span v-else>noComp</span>
      </div>
    </o-modal>
    <o-modal
      v-model="nodeDataModal"
      :title="$srv.getI18nByValue('节点自定义属性')"
      :size="[400, 300]"
      :mask="true"
      :tap-close="true"
      :keep-alive="true"
    >
      <div class="init-container" slot="content">
        <node-data-editor
          :compBoxInfo="GT_compBoxInfo"
          :selectCell="curModifyCell"
          :isShow="nodeDataModal"
        ></node-data-editor>
      </div>
    </o-modal>
  </div>
</template>

<script lang="ts">
import oModal from '@/components/base/modal/o-modal/index.vue';
import {
  blankContentMenuItem,
  getCf,
  I_cmd,
  ifs,
  N_cFlowchart,
  N_oContextMenu,
  saveDetFields,
  T_cmd,
  T_srv,
  ts,
  Tsrv,
  vue
} from './config';
import nodeDataEditor from './nodeDataEditor.vue';
import openBpmn from './open.vue';

@T_srv.comp({
  components: {
    nodeDataEditor,
    openBpmn,
    oModal
  }
})
export default class cBpmn extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private name: string = 'cBpmn';

  private funName: string = '';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  public conf: N_cFlowchart.I_conf = null;

  public cFlowchart: N_cFlowchart.cFlowchart = null;

  public showOpenBpmn: boolean = false;

  public openModal: boolean = false;

  public nodeDataModal: boolean = false;

  private rightPanelForm: any = null;

  private baseGridRef: any = null;

  private curModifyCell: any = null;

  get bpmnAuditState(): string | number | boolean {
    return this.GT_command.getGraphformDataMap().get(
      Tsrv.globalVar.fieldName._audited_
    ).value;
  }

  @T_srv.watch('bpmnAuditState')
  onBpmnAuditStateChange(val: number) {
    this.handleBpmnAuditStateChange(val);
  }

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  private init() {
    this.funName = this.name; // 当前配置中的功能名
    const cf = getCf();
    cf.regEvent = this.GT_command.regGraphEvents;
    cf.regToolbarEvent = this.GT_command.regToolbarEvents;
    this.conf = cf;
  }

  /* 组件挂载 */
  public cFlowchartMounted(compboxInfo: ifs.I_compBoxInfo) {
    this.cFlowchart = compboxInfo.TcompBox.getCompMergeName(
      compboxInfo.compID,
      'cFlowchart'
    );
  }

  /* 设置组件整体遮罩 */
  public setMask(p: boolean) {
    this.cFlowchart.isMask = p;
  }

  public getMask(p: boolean): boolean {
    return this.cFlowchart.isMask;
  }

  private showModal(s: 'open') {
    this.openModal = true;
    this.showOpenBpmn = s === 'open';
    if (this.baseGridRef && s === 'open') {
      this.baseGridRef.GT_editor.loadTableData();
    }
  }

  private hideModal() {
    this.openModal = false;
  }

  public showNodeModal(cell: any) {
    this.curModifyCell = cell;
    this.nodeDataModal = true;
  }

  public nodeContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    const contentMenuItem = this.GT_command.handleMenuItems(e);
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时不允许的右键菜单
      this.cFlowchart.displayContextMenu(
        pos,
        // contentMenuItem.filter(el => !/^add/.test(el.name)),
        [],
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, contentMenuItem, e);
  }

  public edgeContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    const contentMenuItem = this.GT_command.handleMenuItems(e);
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时不允许的右键菜单
      this.cFlowchart.displayContextMenu(
        pos,
        // contentMenuItem.filter(el => !/^add/.test(el.name)),
        [],
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, contentMenuItem, e);
  }

  public blankContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时不允许的右键菜单
      this.cFlowchart.displayContextMenu(
        pos,
        blankContentMenuItem().filter(el => !/^export/.test(el.name)),
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, blankContentMenuItem(), e);
  }

  // 右键菜单选择
  public flowchartContextMenuSelected(
    key: string,
    cmd: N_cFlowchart.I_cFlowCmd
  ) {
    this.GT_command.flowchartContextMenuSelected(key, cmd);
  }

  public graphEditorState(v: N_cFlowchart.I_editorState) {
    this.GT_command.graphEditorState = v;
  }

  public openBpmnDblclick(row: any) {
    this.GT_command.loadBpmnData(row);
    this.hideModal();
  }

  public onRightFormAttrChange(e) {
    switch (e.data.property) {
      case Tsrv.globalVar.fieldName.verNum:
        this.GT_command.setVerNumOfForm(
          e.data.data[Tsrv.globalVar.fieldName.verNum]
        );
        break;
      case Tsrv.globalVar.fieldName.title:
        this.GT_command.setTitleOfForm(
          e.data.data[Tsrv.globalVar.fieldName.title]
        );
        break;
      case Tsrv.globalVar.fieldName.fCode:
        this.GT_command.setFCodeOfForm(
          e.data.data[Tsrv.globalVar.fieldName.fCode]
        );
        break;
      case Tsrv.globalVar.fieldName.m2oFunTitle:
        // this.GT_command.setFunIdOfForm(
        //   e.data.data[Tsrv.globalVar.fieldName.funID],
        //   e.data.data[Tsrv.globalVar.fieldName.m2oFunTitle]
        // );
        this.setFunIdOfForm({
          id: e.data.data[Tsrv.globalVar.fieldName.funID],
          name: e.data.data[Tsrv.globalVar.fieldName.m2oFunTitle]
        });
        // this.GT_command.setVerNumOfForm(6);
        break;

      default:
        throw new Error('未定义的属性');
    }
  }

  private async setFunIdOfForm(funInfo: { id: string; name: string }) {
    try {
      const filter = new ts.T_filter();
      filter.filter = filter.parseFvs([
        new ts.T_fv().setField('_sys_fun_id').setValue(funInfo.id)
      ]);
      const params = {
        filter
      };
      const [b, res, rows, err] = await this.GT_command.getBpmnData(params);
      this.GT_command.setFunIdOfForm(funInfo.name, funInfo.id);
      if (b) {
        if (rows.length > 0) {
          const find = rows.reduce((maxObj, currentObj) =>
            currentObj.id > maxObj.id ? currentObj : maxObj
          );
          if (!Tsrv.noValue(find)) {
            this.GT_command.setVerNumOfForm(Math.trunc(find.ver_num + 1));
          }
          this.setRightFormValue();
          return true;
        }
        this.GT_command.setVerNumOfForm(0);
        this.setRightFormValue();
        return true;
      }
      // this.GT_command.setVerNumOfForm(0);
      this.setRightFormValue();
      return true;
    } catch (error) {
      console.error(error);
      return false;
    }
  }

  public initRightForm(e) {
    this.rightPanelForm = e;
    const columns: Array<any> = this.rightPanelForm.transformColumns(
      saveDetFields()
    );
    this.rightPanelForm.setColumns(columns);
    // 初始化值
    if (!Tsrv.noValue(this.GT_command.graphFormData)) {
      this.rightPanelForm.setFormData(
        this.fvArrToObj(this.GT_command.graphFormData)
      );
    }
    this.rightPanelForm.setColumnNumber(1, true);
    this.rightPanelForm.setModify(false);
  }

  public setRightFormValue() {
    this.rightPanelForm.setFormData(
      this.fvArrToObj(this.GT_command.graphFormData)
    );
  }

  private fvArrToObj(arr: Array<ifs.I_fv>): any {
    const obj: any = {};
    arr.forEach((o: any) => {
      obj[o.field] = o.value;
    });
    return obj;
  }

  public setRightFormModify(b: boolean) {
    if (!Tsrv.noValue(this.rightPanelForm)) {
      this.rightPanelForm.setModify(b);
    }
  }

  public onBgMounted(e) {
    this.baseGridRef = e;
  }

  private handleBpmnAuditStateChange(val: number) {
    this.cFlowchart.GT_cmd.setBtnState('c-audit', 'disabled', val === 1);
  }
}
</script>
<style lang="scss" scoped>
.right-panel {
  border: 1px solid #ccc;
  padding: 6px;
}
.x6-node text {
  white-space: nowrap; /* 禁止文本换行 */
  overflow: hidden; /* 隐藏溢出内容 */
  text-overflow: ellipsis; /* 溢出时显示省略号 */
  width: 100%; /* 宽度适应容器 */
  text-anchor: middle; /* 文本水平居中（SVG 属性） */
  dominant-baseline: middle; /* 文本垂直居中（SVG 属性） */
}
</style>
